package dwl.graduation.design.service.impl;

import cn.hutool.core.util.NumberUtil;
import dwl.graduation.design.algorithm.DBScan;
import dwl.graduation.design.config.SnowflakeConfig;
import dwl.graduation.design.domain.Point;
import dwl.graduation.design.domain.SysCollect;
import dwl.graduation.design.domain.SysCollectExample;
import dwl.graduation.design.mapper.SysCollectMapper;
import dwl.graduation.design.service.AlgorithmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AlgorithmServiceImpl implements AlgorithmService {

    @Autowired
    private SysCollectMapper sysCollectMapper;

    @Autowired
    private SnowflakeConfig snowflakeConfig;


    @Override
    public void showDBSCAN() {
        List<Double> memUsageList = getMemList();
        ArrayList<Point> pointList = new ArrayList<>();
        double y = 0;
        for(Double x:memUsageList){
            y = y+0.1;
            pointList.add(new Point(x,y));
        }
        DBScan dbScan = new DBScan(3,3);
        dbScan.process(pointList);
        Long snowId = snowflakeConfig.snowflakeId();
        String path = "D:\\DBSCAN"+snowId+".txt";
        writeTxt(pointList,path);
    }

    @Override
    public void showForest() {
        List<Double> memUsageList = getMemList();
        List<Object> exportData = new ArrayList<Object>();
        exportData.add("num");
        exportData.add("mem");
        List<List<Object>> dataList = new ArrayList<List<Object>>();
        for(int i=1;i<=memUsageList.size();i++){
            List<Object> data=new ArrayList<Object>();
            data.add(i);
            data.add(memUsageList.get(i-1));
            dataList.add(data);
        }
        String path = "D:\\notebook\\聚类算法\\Cluster\\";
        Long snowId = snowflakeConfig.snowflakeId();
        String fileName = "forest"+snowId;
        createCSVFile(exportData,dataList,path,fileName);
    }

    private List<Double> getMemList(){
        Date zero = getDate(0,0,0);
        Date last = getDate(24,59,59);
        SysCollectExample sysCollectExample = new SysCollectExample();
        sysCollectExample.createCriteria().andCreateTimeBetween(zero,last);
        List<SysCollect> sysCollectList = sysCollectMapper.selectByExample(sysCollectExample);
        return sysCollectList.stream().map(SysCollect::getMemUsage).collect(Collectors.toList());
    }

    private Date getDate(Integer hour,Integer minute,Integer second){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY,hour);
        calendar.set(Calendar.MINUTE,minute);
        calendar.set(Calendar.SECOND,second);
        return calendar.getTime();
    }

    private void  writeTxt(ArrayList<Point> points,String path){
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter(path));
                for (Point point:points) {
                    bw.write(point.toString()+"\n");
                }
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    private File createCSVFile(List<Object> head, List<List<Object>> dataList, String outPutPath, String filename) {

        File csvFile = null;
        BufferedWriter csvWtriter = null;
        try {
            csvFile = new File(outPutPath + File.separator + filename + ".csv");
            File parent = csvFile.getParentFile();
            if (parent != null && !parent.exists()) {
                parent.mkdirs();
            }
            csvFile.createNewFile();

            // GB2312使正确读取分隔符","
            csvWtriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
                    csvFile), "GBK"), 1024);
            // 写入文件头部
            writeRow(head, csvWtriter);

            // 写入文件内容
            for (List<Object> row : dataList) {
                writeRow(row, csvWtriter);
            }
            csvWtriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                csvWtriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return csvFile;
    }

    private void writeRow(List<Object> row, BufferedWriter csvWriter) throws IOException {
        // 写入文件头部
        for (Object data : row) {
            StringBuffer sb = new StringBuffer();
            String rowStr = sb.append("\"").append(data).append("\",").toString();
            csvWriter.write(rowStr);
        }
        csvWriter.newLine();
    }

}
